import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; import java.util.Set; // define shell of a Graph class class Graph { LinkedList<Vertex> vertices; private LinkedList<EdgeIfc> edges; Graph() { vertices = new LinkedList<Vertex>(); edges = new LinkedList<EdgeIfc>(); } public VertexIter getVertices() { return new VertexIter(this); } public EdgeIter getEdges() { // if not using GEN than we must build the edges on the fly if (false && edgesNotBuilt) { edgesNotBuilt = false; edges = new LinkedList<EdgeIfc>(); int k1 = 0, k2 = 0, sizeAV = 0; // G Neighbor tempNeighbor;// GN for (VertexIter vxiter = getVertices(); vxiter.hasNext();) { Vertex v = vxiter.next(); sizeAV = v.adjacentVertices.size();// G sizeAV = v.adjacentNeighbors.size();// GN for (k2 = 0; k2 < sizeAV; k2++) { // G edges.add(new Edge(v, v.adjacentVertices.get(k2), v.weightsList.get(k2).intValue())); // GN tempNeighbor = v.adjacentNeighbors.get(k2); edges.add(new Edge(v, tempNeighbor.neighbor, tempNeighbor.weight)); } // of k2 } // of k1 } return new EdgeIter() { private Iterator<EdgeIfc> iter = edges.iterator(); public EdgeIfc next() { return iter.next(); } public boolean hasNext() { return iter.hasNext(); } }; } boolean edgesNotBuilt = true; public void sortVertices(Comparator<Vertex> c) { Collections.sort(vertices, c); } public void sortEdges(Comparator<EdgeIfc> c) { Collections.sort(edges, c); } // methods whose bodies will be overridden later EdgeIfc addEdge(Vertex start, Vertex end, int weight) { // G start.addAdjacent(end); end.addAdjacent(start);// undirected start.setWeight(weight); end.addWeight(weight); if (true) return (EdgeIfc) start; // GN Neighbor e = new Neighbor(end, weight); addEdge(start, e); if (true) return e; // GEN Edge theEdge = new Edge(start, end, weight); edges.add(theEdge); start.addNeighbor(new Neighbor(end, theEdge)); end.addNeighbor(new Neighbor(start, theEdge));// undirected if (true) return theEdge; return null; } public void addEdge(Vertex start, Neighbor theNeighbor) { start.addEdge(theNeighbor); Vertex end = theNeighbor.neighbor; end.addEdge(new Neighbor(start, theNeighbor.weight)); } Vertex findsVertex(String name) { Vertex theVertex; // if we are dealing with the root if (name == null) return null; for (VertexIter vxiter = getVertices(); vxiter.hasNext();) { theVertex = vxiter.next(); if (name.equals(theVertex.getName())) { return theVertex; } } return null; } void display() { System.out.println("******************************************"); System.out.println("Vertices "); for (int i = 0; i < vertices.size(); i++) vertices.get(i).display(); System.out.println("******************************************"); System.out.println("Edges "); for (EdgeIter edgeiter = getEdges(); edgeiter.hasNext();) edgeiter.next().display(); System.out.println("******************************************"); } void addVertex(Vertex v) { vertices.add(v); } public Reader inFile; // File handler for reading public static int ch; // Character to read/write // timings static long last = 0, current = 0, accum = 0; public void runBenchmark(String FileName) throws IOException { try { inFile = new FileReader(FileName); } catch (IOException e) { System.out.println("Your file " + FileName + " cannot be read"); } } public void stopBenchmark() throws IOException { inFile.close(); } public int readNumber() throws IOException { int index = 0; char[] word = new char[80]; int ch = 0; ch = inFile.read(); while (ch == 32) { ch = inFile.read(); // skips extra whitespaces } while (ch != -1 && ch != 32 && ch != 10) // while it is not EOF, WS, // NL { word[index++] = (char) ch; ch = inFile.read(); } word[index] = 0; String theString = new String(word); theString = new String(theString.substring(0, index)).trim(); return Integer.parseInt(theString, 10); } public static void startProfile() { accum = 0; current = System.currentTimeMillis(); last = current; } public static void stopProfile() { current = System.currentTimeMillis(); accum = accum + (current - last); } public static void resumeProfile() { current = System.currentTimeMillis(); last = current; } public static void endProfile() { current = System.currentTimeMillis(); accum = accum + (current - last); System.out.println("Time elapsed: " + accum + " milliseconds"); } // method is extended later public void run(Vertex v) { // connectedComponents(); // System.out.println(" Cycle? " + cycleCheck()); // Graph gaux = kruskal(); Graph.stopProfile(); gaux.display(); Graph.resumeProfile(); // Graph gaux1 = prim(v); Graph.stopProfile(); gaux1.display(); Graph.resumeProfile(); // numberVertices(); // Graph gaux2 = strongComponents(); Graph.stopProfile(); gaux2.display(); Graph.resumeProfile(); } public EdgeIfc findsEdge(Vertex theSource, Vertex theTarget) { Vertex v1 = theSource; for (EdgeIter edgeiter = v1.getEdges(); edgeiter.hasNext();) { EdgeIfc theEdge = edgeiter.next(); Vertex v2 = theEdge.getOtherVertex(v1); if ((v1.getName().equals(theSource.getName()) && v2.getName() .equals(theTarget.getName())) || (v1.getName().equals(theTarget.getName()) && v2 .getName().equals(theSource.getName()))) return theEdge; } return null; } public void graphSearch(WorkSpace w) { // Step 1: initialize visited member of all nodes VertexIter vxiter = getVertices(); if (vxiter.hasNext() == false) { return; } // Showing the initialization process while (vxiter.hasNext()) { Vertex v = vxiter.next(); v.init_vertex(w); } // Step 2: traverse neighbors of each node for (vxiter = getVertices(); vxiter.hasNext();) { Vertex v = vxiter.next(); if (!v.visited) { w.nextRegionAction(v); v.nodeSearch(w); } } // end for } public void numberVertices() { graphSearch(new NumberWorkSpace()); } public void connectedComponents() { graphSearch(new RegionWorkSpace()); } public Graph strongComponents() { FinishTimeWorkSpace FTWS = new FinishTimeWorkSpace(); // 1. Computes the finishing times for each vertex graphSearch(FTWS); // 2. Order in decreasing & call DFS Transposal sortVertices(new Comparator<Vertex>() { public int compare(Vertex v1, Vertex v2) { if (v1.finishTime > v2.finishTime) return -1; if (v1.finishTime == v2.finishTime) return 0; return 1; } }); // 3. Compute the transpose of G // Done at layer transpose Graph gaux = computeTranspose((Graph) this); // 4. Traverse the transpose G WorkSpaceTranspose WST = new WorkSpaceTranspose(); gaux.graphSearch(WST); return gaux; } // of Strong Components public Graph computeTranspose(Graph the_graph) { int i; String theName; Map newVertices = new HashMap(); // Creating the new Graph Graph newGraph = new Graph(); // Creates and adds the vertices with the same name for (VertexIter vxiter = getVertices(); vxiter.hasNext();) { theName = vxiter.next().getName(); Vertex v = new Vertex().assignName(theName); newGraph.addVertex(v); newVertices.put(theName, v); } Vertex theVertex, newVertex; Vertex theNeighbor; Vertex newAdjacent; EdgeIfc newEdge; // adds the transposed edges VertexIter newvxiter = newGraph.getVertices(); for (VertexIter vxiter = getVertices(); vxiter.hasNext();) { // theVertex is the original source vertex // the newAdjacent is the reference in the newGraph to theVertex theVertex = vxiter.next(); newAdjacent = newvxiter.next(); for (VertexIter neighbors = theVertex.getNeighbors(); neighbors .hasNext();) { // Gets the neighbor object theNeighbor = neighbors.next(); // the new Vertex is the vertex that was adjacent to theVertex // but now in the new graph newVertex = (Vertex) newVertices.get(theNeighbor.getName()); // Creates a new Edge object and adjusts the adornments newEdge = newGraph.addEdge(newVertex, newAdjacent, 0); } // all adjacentNeighbors } // all the vertices return newGraph; } // of ComputeTranspose public boolean cycleCheck() { CycleWorkSpace c = new CycleWorkSpace(); graphSearch(c); return c.AnyCycles; } public Graph kruskal() { // 1. A <- Empty set LinkedList A = new LinkedList(); // 2. for each vertex v E V[G] // 3. do Make-Set(v) for (VertexIter vxiter = getVertices(); vxiter.hasNext();) { Vertex v = vxiter.next(); v.representative = v; // I am in my set v.members = new LinkedList(); // I have no members in my set } // 4. sort the edges of E by nondecreasing weight w // Creates the edges objects // int j; LinkedList Vneighbors = new LinkedList(); // Vertex u; // this was added to support GnR and GR because there are no // edge objects b4 this point. EdgeIter dummyIter = getEdges(); // Sort the Edges in non decreasing order sortEdges(new Comparator<EdgeIfc>() { public int compare(EdgeIfc e1, EdgeIfc e2) { if (e1.getWeight() < e2.getWeight()) return -1; if (e1.getWeight() == e2.getWeight()) return 0; return 1; } }); // 5. for each edge in the nondecresing order Vertex vaux, urep, vrep; for (EdgeIter edgeiter = getEdges(); edgeiter.hasNext();) { // 6. if Find-Set(u)!=Find-Set(v) EdgeIfc e1 = edgeiter.next(); Vertex u = e1.getStart(); Vertex v = e1.getEnd(); if (!(v.representative.getName()) .equals(u.representative.getName())) { // 7. A <- A U {(u,v)} A.add(e1); // 8. Union(u,v) urep = u.representative; vrep = v.representative; if ((urep.members ).size() > (vrep.members ).size()) { // we // add // elements // of v // to u for (int j = 0; j < (vrep.members ).size(); j++) { vaux = (Vertex) (vrep.members ).get(j); vaux.representative = urep; (urep.members ).add(vaux); } v.representative = urep; vrep.representative = urep; (urep.members ).add(v); if (!v.equals(vrep)) (urep.members ).add(vrep); (vrep.members ).clear(); } else { // we add elements of u to v for (int j = 0; j < (urep.members ).size(); j++) { vaux = (Vertex) (urep.members ).get(j); vaux.representative = vrep; (vrep.members ).add(vaux); } u.representative = vrep; urep.representative = vrep; (vrep.members ).add(u); if (!u.equals(urep)) (vrep.members ).add(urep); (urep.members ).clear(); } // else } // of if } // of for numedges // 9. return A // Creates the new Graph that contains the SSSP String theName; Graph newGraph = new Graph(); // Creates and adds the vertices with the same name for (VertexIter vxiter = getVertices(); vxiter.hasNext();) { theName = vxiter.next().getName(); newGraph.addVertex(new Vertex().assignName(theName)); } // Creates the edges from the NewGraph Vertex theStart, theEnd; Vertex theNewStart, theNewEnd; EdgeIfc theEdge; // For each edge in A we find its two vertices // make an edge for the new graph from with the correspoding // new two vertices for (int i = 0; i < A.size(); i++) { // theEdge with its two vertices theEdge = (EdgeIfc) A.get(i); theStart = theEdge.getStart(); theEnd = theEdge.getEnd(); // Find the references in the new Graph theNewStart = newGraph.findsVertex(theStart.getName()); theNewEnd = newGraph.findsVertex(theEnd.getName()); // Creates the new edge with new start and end vertices // in the newGraph // and ajusts the adorns based on the old edge // Adds the new edge to the newGraph EdgeIfc theNewEdge = newGraph.addEdge(theNewStart, theNewEnd, theEdge.getWeight()); theNewEdge.adjustAdorns(theEdge); } return newGraph; } // kruskal public Graph prim(Vertex r) { Vertex root; root = r; Vertex x; // 2. and 3. Initializes the vertices for (VertexIter vxiter = getVertices(); vxiter.hasNext();) { x = vxiter.next(); x.pred = null; x.key = Integer.MAX_VALUE; } // 4. and 5. root.key = 0; root.pred = null; // 2. S <- empty set // 1. Queue <- V[G], copy the vertex in the graph in the priority queue LinkedList<Vertex> queue = new LinkedList<Vertex>(); Set<String> indx = new HashSet<String>(); // Inserts the root at the head of the queue queue.add(root); indx.add(root.getName()); for (VertexIter vxiter = getVertices(); vxiter.hasNext();) { x = vxiter.next(); if (x.key != 0) // this means, if this is not the root { queue.add(x); indx.add(x.getName()); } } // Inserts the root at the head of the queue // Queue.addFirst( root ); // 6. while Q!=0 int k; LinkedList<NeighborIfc> uneighbors; Vertex u, v; EdgeIfc en; NeighborIfc vn; int wuv; boolean isNeighborInQueue = false; // Queue is a list ordered by key values. // At the beginning all key values are INFINITUM except // for the root whose value is 0. while (queue.size() != 0) { // 7. u <- Extract-Min(Q); // Since this is an ordered queue the first element is the min u = (Vertex) queue.removeFirst(); indx.remove(u.getName()); // 8. for each vertex v adjacent to u uneighbors = u.getNeighborsObj(); k = 0; for (EdgeIter edgeiter = u.getEdges(); edgeiter.hasNext(); k++) { vn = (NeighborIfc) uneighbors.get(k); en = edgeiter.next(); v = en.getOtherVertex(u); // Check to see if the neighbor is in the queue isNeighborInQueue = false; // if the Neighor is in the queue if (indx.contains(v.getName())) isNeighborInQueue = true; wuv = en.getWeight(); // 9. Relax (u,v w) if (isNeighborInQueue && (wuv < v.key)) { v.key = wuv; v.pred = u.getName(); uneighbors.set(k, vn); // adjust values in the neighbors // update the values of v in the queue // Remove v from the Queue so that we can reinsert it // in a new place according to its new value to keep // the Linked List ordered Object residue = (Object) v; queue.remove(residue); // Object residue = Queue.remove( indexNeighbor ); indx.remove(v.getName()); // Get the new position for v int position = Collections.binarySearch(queue, v, new Comparator<Vertex>() { public int compare(Vertex v1, Vertex v2) { if (v1.key < v2.key) return -1; if (v1.key == v2.key) return 0; return 1; } }); // Adds v in its new position in Queue if (position < 0) // means it is not there { queue.add(-(position + 1), v); } else // means it is there { queue.add(position, v); } indx.add(v.getName()); } // if 8-9. } // for all neighbors } // of while // Creates the new Graph that contains the SSSP String theName; Graph newGraph = new Graph(); // Creates and adds the vertices with the same name for (VertexIter vxiter = getVertices(); vxiter.hasNext();) { Vertex vtx = vxiter.next(); theName = vtx.name; newGraph.addVertex(new Vertex().assignName(theName)); } // Creates the edges from the NewGraph Vertex theVertex, thePred; Vertex theNewVertex, theNewPred; EdgeIfc e; // Creates and adds the vertices with the same name for (VertexIter vxiter = getVertices(); vxiter.hasNext();) { // theVertex and its Predecessor theVertex = vxiter.next(); thePred = findsVertex(theVertex.pred); // if theVertex is the source then continue we dont need // to create a new edge at all if (thePred == null) continue; // Find the references in the new Graph theNewVertex = newGraph.findsVertex(theVertex.name); theNewPred = newGraph.findsVertex(thePred.name); // Creates the new edge from predecessor -> vertex in the newGraph // and ajusts the adorns based on the old edge EdgeIfc theNewEdge = newGraph.addEdge(theNewPred, theNewVertex, 0); e = findsEdge(thePred, theVertex); theNewEdge.adjustAdorns(e); } return newGraph; } // MST }